home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Source Code / Visual Basic Source Code.iso / vbsource / vbalyz / mfuncs.bas < prev    next >
BASIC Source File  |  1995-01-05  |  21KB  |  840 lines

  1. Option Explicit
  2.  
  3. Global Const APP_NAME = "VB*Alyzer"
  4.  
  5. Dim mblnProjectSelected As Integer
  6. Dim mstrProjectName  As String
  7.  
  8. Dim mstraProjFile() As String
  9.  
  10. Type Metric_Type
  11.     Name As String
  12.     LongName As String
  13.     Display As Integer
  14. End Type
  15.  
  16. Dim muaMetric(1 To 20) As Metric_Type
  17.  
  18. Type FileStats_Type
  19.     Filename As String
  20.     Metric(1 To 20)  As Single
  21.     CurrentBeginEndLevel As Integer
  22.     CurrentFunc As String
  23.     CurrentComplexity As Integer
  24.     WorstRoutine As String
  25. End Type
  26.  
  27. Type Status_Type
  28.     InRoutine As Integer
  29.     InType As Integer
  30. End Type
  31.  
  32. Dim muStatus As Status_Type
  33.  
  34. Const TOTSIZE = 1
  35. Const TOTLINES = 2
  36. Const BLANKLINES = 3
  37. Const TOTCOMMENTS = 4
  38. Const TOTROUTINES = 5
  39. Const PRIVATEROUTINES = 6
  40. Const LOCALVARS = 7
  41. Const LOCALCONSTS = 8
  42. Const MODULEVARS = 9
  43. Const MODULECONSTS = 10
  44. Const GLOBALVARS = 11
  45. Const GLOBALCONSTS = 12
  46. Const APIDECS = 13
  47. Const TYPES = 14
  48. Const TYPELINES = 15
  49. Const AVERTNLINES = 16
  50. Const RTNNONCODELINES = 17
  51. Const ROUTINECODELINES = 18
  52. Const ROUTINEDECPTS = 19
  53. Const MOSTCOMPLEX = 20
  54.  
  55. Dim muTotStat As FileStats_Type
  56.  
  57. Sub AccumTotals (uStatIn As FileStats_Type)
  58.  
  59. ' Add the values in the supplied stat record to the total record
  60.  
  61. Dim i As Integer
  62.  
  63.     For i = LBound(uStatIn.Metric) To UBound(uStatIn.Metric)
  64.         If i <> MOSTCOMPLEX Then
  65.             muTotStat.Metric(i) = muTotStat.Metric(i) + uStatIn.Metric(i)
  66.         Else
  67.             ' MostComplex should be a maximum
  68.             If muTotStat.Metric(i) < uStatIn.Metric(i) Then
  69.                 muTotStat.Metric(i) = uStatIn.Metric(i)
  70.             End If
  71.         End If
  72.     Next
  73.  
  74. End Sub
  75.  
  76. Sub AnalyzeCurrentProject (lst As Control, grd As Grid)
  77.  
  78. Dim i As Integer
  79.  
  80.     Screen.MousePointer = HOURGLASS
  81.  
  82.     ' Reset output grid
  83.     ClearWholeGrid grd
  84.     grd.Rows = 1
  85.     SetGridHeadings grd
  86.  
  87.     ZeroProjectTotals
  88.  
  89.     ' For each file in list, take it apart
  90.     For i = 0 To lst.ListCount - 1
  91.         AnalyzeFile lst.List(i), grd
  92.     Next
  93.  
  94.     ' Display stats
  95.     ReportStats muTotStat, grd
  96.  
  97.     Screen.MousePointer = DEFAULT
  98.  
  99. End Sub
  100.  
  101. Sub AnalyzeFile (ByVal strFile As String, grd As Grid)
  102.  
  103. Dim intF As Integer
  104. Dim strLine As String
  105. Dim uStat As FileStats_Type
  106.  
  107.     intF = FreeFile
  108.  
  109.     Open strFile For Input As intF
  110.  
  111.     muStatus.InRoutine = False
  112.     uStat.Filename = strFile
  113.  
  114.     Do
  115.         Line Input #intF, strLine
  116.         AnalyzeLine strLine, uStat
  117.     Loop Until EOF(intF)
  118.  
  119.     ' Check last routine's complexity
  120.     If muStatus.InRoutine Then
  121.         CheckComplexity uStat, strLine
  122.     End If
  123.  
  124.     Close intF
  125.  
  126.     ReportStats uStat, grd
  127.  
  128.     AccumTotals uStat
  129.  
  130. End Sub
  131.  
  132. Sub AnalyzeLine (ByVal strLine As String, uStat As FileStats_Type)
  133.  
  134. ' This is the main engine for the whole metric part of the program
  135. ' It's not very nice, and should probably be broken up. Sooner rather
  136. ' than later.
  137.  
  138.     ' Add Line lingth to total size
  139.     uStat.Metric(TOTSIZE) = uStat.Metric(TOTSIZE) + Len(strLine)
  140.     
  141.     ' Remove leading/trailing spaces
  142.     strLine = Trim$(strLine)
  143.  
  144.     ' If working on a form, ignore control description info,
  145.     ' identifiable by "Begin" and "End". Keep track of current
  146.     ' "level": while > 0 we're still working in the uninteresting
  147.     ' part of the file.
  148.     If Right$(uStat.Filename, 3) = "FRM" Then
  149.         If IsLeftEnd(strLine, "Begin") Then
  150.             uStat.CurrentBeginEndLevel = uStat.CurrentBeginEndLevel + 1
  151.             Exit Sub
  152.         End If
  153.         If uStat.CurrentBeginEndLevel > 0 Then
  154.             If IsLeftEnd(strLine, "End") Then
  155.                 uStat.CurrentBeginEndLevel = uStat.CurrentBeginEndLevel - 1
  156.                 Exit Sub
  157.             End If
  158.         End If
  159.         If uStat.CurrentBeginEndLevel > 0 Then
  160.             Exit Sub
  161.         End If
  162.     End If
  163.  
  164.     ' Increment total lines
  165.     inc uStat, TOTLINES
  166.     
  167.     ' If blank line, increment blank count
  168.     If Len(strLine) = 0 Then
  169.         inc uStat, BLANKLINES
  170.         ' If blank is in a routine, increment non-code line count
  171.         If muStatus.InRoutine Then
  172.             inc uStat, RTNNONCODELINES
  173.         End If
  174.         Exit Sub
  175.     End If
  176.  
  177.     ' If comment... (Note no allowance made for trailing comments)
  178.     If Left$(strLine, 1) = "'" Then
  179.         inc uStat, TOTCOMMENTS
  180.         If muStatus.InRoutine Then
  181.             inc uStat, RTNNONCODELINES
  182.         End If
  183.         Exit Sub
  184.     End If
  185.  
  186.     If IsLeftEnd(strLine, "Private") Then
  187.         inc uStat, PRIVATEROUTINES
  188.         StripLeftmostWord strLine
  189.     End If
  190.  
  191.     ' Check current line for being a routine (= Sub or Function)
  192.     If IsRoutine(strLine) Then
  193.         
  194.         muStatus.InRoutine = True
  195.         inc uStat, TOTROUTINES
  196.     
  197.         CheckComplexity uStat, strLine
  198.  
  199.         ' Uses McCabe complexity metric, counting decision points.
  200.         ' A routine's Decision Pt count is always 1, even if
  201.         ' there's nothing else of significance in the routine
  202.         inc uStat, ROUTINEDECPTS
  203.         uStat.CurrentComplexity = 1
  204.  
  205.         ' Get routine name by removing the Sub or Function part...
  206.         StripLeftmostWord strLine
  207.  
  208.         ' ...and taking the next word
  209.         uStat.CurrentFunc = LeftMostWord(strLine)
  210.         
  211.         Exit Sub
  212.     End If
  213.  
  214.     ' Are we defining a variable?
  215.     If IsLeftEnd(strLine, "Dim") Then
  216.         If muStatus.InRoutine Then
  217.             inc uStat, LOCALVARS
  218.             inc uStat, RTNNONCODELINES
  219.         Else
  220.             inc uStat, MODULEVARS
  221.         End If
  222.         Exit Sub
  223.     End If
  224.  
  225.     ' How about a Constant?
  226.     If IsLeftEnd(strLine, "Const") Then
  227.         If muStatus.InRoutine Then
  228.             inc uStat, LOCALCONSTS
  229.             inc uStat, RTNNONCODELINES
  230.         Else
  231.             inc uStat, MODULECONSTS
  232.         End If
  233.         Exit Sub
  234.     End If
  235.  
  236.     ' Is something being defined globally?
  237.     If IsLeftEnd(strLine, "Global") Then
  238.         ' Is it a constant?
  239.         If InStr(strLine, " Const ") Then
  240.             inc uStat, GLOBALCONSTS
  241.         Else
  242.         ' If not, it must be a variable of some sort
  243.             inc uStat, GLOBALVARS
  244.         End If
  245.         Exit Sub
  246.     End If
  247.  
  248.     ' Check for API declarations (includes all DLL links)
  249.     If IsLeftEnd(strLine, "Declare Sub") Or IsLeftEnd(strLine, "Declare Function") Then
  250.         inc uStat, APIDECS
  251.         Exit Sub
  252.     End If
  253.  
  254.     ' If we're not currently processing a Type, then check to see
  255.     ' if one's just turned up...
  256.     If Not muStatus.InType Then
  257.         ' If it has, then record the fact
  258.         If IsLeftEnd(strLine, "Type") Then
  259.             muStatus.InType = True
  260.             inc uStat, TYPES
  261.             Exit Sub
  262.         End If
  263.     End If
  264.  
  265.     ' if we're in a Type declaration,
  266.     If muStatus.InType Then
  267.         ' Check for the end of it
  268.         If IsLeftEnd(strLine, "End Type") Then
  269.             muStatus.InType = False
  270.             inc uStat, TYPELINES
  271.         Else
  272.             inc uStat, TYPELINES
  273.         End If
  274.         Exit Sub
  275.     End If
  276.  
  277.     ' If we're in a routine, check this line for decision
  278.     ' points.
  279.     If muStatus.InRoutine Then
  280.         CountDecisionPoints strLine, uStat
  281.         ' Since we've got this far, and exited earlier if
  282.         ' non-"action code" lines were encountered, it's a
  283.         ' reasonable bet that this line _is_ "action code"
  284.         inc uStat, ROUTINECODELINES
  285.     End If
  286.  
  287. End Sub
  288.  
  289. Sub CheckComplexity (uStat As FileStats_Type, strLine As String)
  290.  
  291.     ' if in a routine, check to see if the last routine was more complex
  292.     ' than that currently stored
  293.     If muStatus.InRoutine Then
  294.         If uStat.CurrentComplexity > uStat.Metric(MOSTCOMPLEX) Then
  295.             uStat.Metric(MOSTCOMPLEX) = uStat.CurrentComplexity
  296.             uStat.WorstRoutine = uStat.CurrentFunc
  297.         End If
  298.     End If
  299.  
  300. End Sub
  301.  
  302. Sub ClearProjectFileList ()
  303.  
  304.     ReDim mstraProjFile(1 To 1)
  305.  
  306. End Sub
  307.  
  308. Sub CountDecisionPoints (ByVal strLine As String, uStat As FileStats_Type)
  309.  
  310. Dim intDecPts As Integer
  311.  
  312.     ' Check for lines beginning Select Case/For/Do/While
  313.     If